package com.zlm.tools.util;

import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Random;

/**
 * 简单公示计算器
 *
 * @author zlm
 * @date 2023/9/16
 */
public class CalcUtil {
    /**
     * 公式
     */
    private String formula;

    /**
     * 公式字符数组
     */
    private char[] val;
    /**
     * 公式长度
     */
    private int length;
    /**
     * 计算的当前位置
     */
    private int index;

    public CalcUtil(String formula) {
        this.formula = formula;
        this.val = formula.toCharArray();
        this.length = val.length;
        index = 0;
    }

    public BigDecimal getResult() {
        return nextData(BigDecimal.ZERO, '+');
    }

    /**
     * 获取下一个值
     *
     * @param param    第一个参数
     * @param operator 参数后的运算符
     * @return 计算值
     */
    private BigDecimal nextData(BigDecimal param, char operator) {
        if (index < length) {
            if (operator == ')') {
                return param;
            }
            if (operator == '+') {
                return param.add(nextData(nextParam(), index < length ? val[index++] : ')'));
            }else if(operator == '*'){
                return nextData(param.multiply(nextParam(), MathContext.DECIMAL32), index < length ? val[index++] : ')');
            } else if (operator == '/') {
                return nextData(param.divide(nextParam(), MathContext.DECIMAL32), index < length ? val[index++] : ')');
            }
        }

        return param;
    }

    private BigDecimal nextParam() {
        char[] param = new char[length - index + 1];
        int paramIndex = 0;
        while (index < length) {
            //将-变为+负数
            if (val[index] == '-') {
                if (paramIndex == 0) {
                    param[paramIndex++] = val[index];
                    param[paramIndex++] = '0';
                } else {
                    val[--index] = '+';
                    break;
                }
                //判断小数和拼接数据  48对应0 57对应9
            }else if(val[index] == '.' || (val[index] >= 48 && val[index] <= 57)){
                param[paramIndex++] = val[index];
            // 40 对应 (
            } else if (val[index] == 40) {
                index++;
                return nextData(BigDecimal.ZERO,'+');
            // 41 对应 )  43 对应 + 47 对应 /
            }else if((val[index] >= 41 && val[index] <= 43) || val[index] == 47){
                break;
            }
            index++;
        }

        return paramIndex > 0 ? new BigDecimal(param,0,paramIndex) : BigDecimal.ZERO;
    }

    public static void main(String[] args) {
        String str = "5-(2-1)";
        CalcUtil calcUtil = new CalcUtil(str);
        System.out.println(calcUtil.getResult());

    }

}
